package com.beiing.leafchat.renderer;


import com.beiing.leafchat.bean.Axis;
import com.beiing.leafchat.bean.AxisValue;
import com.beiing.leafchat.bean.ChartData;
import com.beiing.leafchat.bean.Line;
import com.beiing.leafchat.bean.PointValue;
import com.beiing.leafchat.support.LeafUtil;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.LinearShader;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.render.PathEffect;
import ohos.agp.render.PathMeasure;
import ohos.agp.render.Shader;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.Rect;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

import java.util.List;

import static ohos.agp.render.Paint.ShaderType.LINEAR_SHADER;

/**
 * Created by chenliu on 2017/1/12.<br/>
 * 描述：
 * </br>
 */

public class OutsideLineRenderer extends AbsRenderer {

    /**
     * 填充画笔
     **/
    private Paint fillPaint;

    private PathMeasure measure;

    /**
     * 动画结束标志
     */
    private boolean isAnimateEnd = true;

    /**
     * 是否开始绘制，防止动画绘制之前绘制一次
     */
    private boolean isShow = true;

    private float phase;

    private LinearShader fillShader;

    public OutsideLineRenderer(Context context, Component view) {
        super(context, view);
    }

    @Override
    protected void initPaint() {
        super.initPaint();
        fillPaint = new Paint();
        fillPaint.setStyle(Paint.Style.FILL_STYLE);
    }

    /**
     * 画坐标轴 刻度值
     *
     * @param canvas 绘制信息
     * @param axisX X轴
     * @param axisY Y轴
     * @param moveX 移动距离
     */
    public void drawCoordinateText(Canvas canvas, Axis axisX, Axis axisY, int moveX) {
        if (axisX != null && axisY != null) {
            //////// X 轴
            // 1.刻度
            coordPaint.setColor(new Color(axisX.getTextColor()));
            coordPaint.setTextSize((int) LeafUtil.sp2px(mContext, axisX.getTextSize()));

            Paint.FontMetrics fontMetrics = coordPaint.getFontMetrics(); // 获取标题文字的高度（fontMetrics.descent - fontMetrics.ascent）
            float textH = LeafUtil.add(fontMetrics.descent, -fontMetrics.ascent);

            List<AxisValue> valuesX = axisX.getValues();
            if (axisX.isShowText()) {
                for (int i = 0; i < valuesX.size(); i++) {
                    AxisValue value = valuesX.get(i);
                    if (value.isShowLabel()) {
                        float textW = coordPaint.measureText(value.getLabel());
                        canvas.drawText(coordPaint, value.getLabel(), LeafUtil.add(value.getPointX(), -textW / 2, moveX), LeafUtil.add(value.getPointY(), -textH / 2));
                    }
                }
            }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            /////// Y 轴
            coordPaint.setColor(new Color(axisY.getTextColor()));
            coordPaint.setTextSize((int) LeafUtil.sp2px(mContext, axisY.getTextSize()));

            List<AxisValue> valuesY = axisY.getValues();
            if (axisY.isShowText()) {
                for (AxisValue value : valuesY) {
                    float textW = coordPaint.measureText(value.getLabel());
                    float pointx = LeafUtil.add(value.getPointX(), -1.1f * textW);
                    canvas.drawText(coordPaint, value.getLabel(), pointx, value.getPointY());
                }
            }
        }
    }

    /**
     * 画折线
     *
     * @param canvas 绘制信息
     * @param line 折线信息
     * @param axisY Y轴
     * @param moveX 移动距离
     */
    public void drawLines(Canvas canvas, Line line, Axis axisY, int moveX) {
        if (line != null && isShow) {
            linePaint.setColor(new Color(line.getLineColor()));
            linePaint.setStrokeWidth(LeafUtil.dp2px(mContext, line.getLineWidth()));
            linePaint.setStyle(Paint.Style.STROKE_STYLE);
            List<PointValue> values = line.getValues();
            Path path = line.getPath();
            int size = values.size();
            for (int i = 0; i < size; i++) {
                PointValue point = values.get(i);
                if (i == 0) path.moveTo(LeafUtil.add(point.getOriginX(), moveX), point.getOriginY());
                else path.lineTo(LeafUtil.add(point.getOriginX(), moveX), point.getOriginY());
            }

            measure = new PathMeasure(path, false);
            linePaint.setPathEffect(createPathEffect(measure.getLength(), phase, 0.0f));
            canvas.save();
            canvas.clipRect(axisY.getStartX(), 0, mWidth, mHeight);
            canvas.drawPath(path, linePaint);
            canvas.restore();
        }
    }


    /**
     * 填充
     *
     * @param canvas 绘制信息
     * @param line 填充线信息
     * @param axisX X轴
     * @param moveX 移动距离
     */
    public void drawFillArea(Canvas canvas, Line line, Axis axisX, int moveX) {
        //继续使用前面的 path
        if (line != null && line.getValues().size() > 1 && isShow) {
            List<PointValue> values = line.getValues();
            PointValue firstPoint = values.get(0);
            float firstX = firstPoint.getOriginX();

            Path path = line.getPath();
            PointValue lastPoint = values.get(values.size() - 1);
            float lastX = lastPoint.getOriginX();
            path.lineTo(LeafUtil.add(lastX, moveX), axisX.getStartY());
            path.lineTo(LeafUtil.add(firstX, moveX), axisX.getStartY());
            path.close();

            if (fillShader == null) {
                fillShader = new LinearShader(new Point[]{new Point(0, 0), new Point(0, mHeight)}, new float[]{}, new Color[]{new Color(line.getFillColor()), Color.TRANSPARENT}, Shader.TileMode.CLAMP_TILEMODE);
                fillPaint.setShader(fillShader, LINEAR_SHADER);
            }

            if (line.getFillColor() == 0)
                fillPaint.setAlpha(100);
            else
                fillPaint.setColor(new Color(line.getFillColor()));

            canvas.save();
            canvas.clipRect(firstX, 0, LeafUtil.add(phase * LeafUtil.add(lastX, -firstX), firstX, moveX), mHeight);
            canvas.drawPath(path, fillPaint);
            canvas.restore();
            path.reset();
        }
    }

    /**
     * 画圆点
     *
     * @param canvas 绘制信息
     * @param line 圆点线信息
     * @param axisY Y轴
     * @param moveX 移动距离
     */
    public void drawPoints(Canvas canvas, Line line, Axis axisY, int moveX) {
        if (line != null && line.isHasPoints() && isShow) {
            List<PointValue> values = line.getValues();
            float radius = LeafUtil.dp2px(mContext, line.getPointRadius());
            float strokeWidth = LeafUtil.dp2px(mContext, 1);
            PointValue point;
            canvas.save();
            canvas.clipRect(axisY.getStartX(), 0, mWidth, mHeight);
            for (int i = 0, size = values.size(); i < size; i++) {
                point = values.get(i);
                labelPaint.setStyle(Paint.Style.FILL_STYLE);
                labelPaint.setColor(new Color(line.getPointColor()));
                canvas.drawCircle(LeafUtil.add(point.getOriginX(), moveX), point.getOriginY(),
                        radius, labelPaint);
                labelPaint.setStyle(Paint.Style.STROKE_STYLE);
                labelPaint.setColor(Color.WHITE);
                labelPaint.setStrokeWidth(strokeWidth);
                canvas.drawCircle(LeafUtil.add(point.getOriginX(), moveX), point.getOriginY(),
                        radius, labelPaint);
            }
            canvas.restore();
        }
    }

    public void drawLabels(Canvas canvas, ChartData chartData, Axis axisY, int moveX) {
        if (isAnimateEnd) {
            if (chartData != null) {
                if (chartData.isHasLabels()) {
                    labelPaint.setTextSize((int) LeafUtil.sp2px(mContext, 12));
                    List<PointValue> values = chartData.getValues();
                    int size = values.size();
                    canvas.save();
                    canvas.clipRect(axisY.getStartX(), 0, mWidth, mHeight);
                    for (int i = 0; i < size; i++) {
                        PointValue point = values.get(i);
                        String label = point.getLabel();
                        int length = label.length();
                        Rect textBounds = labelPaint.getTextBounds(label);

                        float textW = textBounds.getWidth();
                        float textH = textBounds.getHeight();
                        float left, top, right, bottom;
                        if (length == 1) {
                            left = LeafUtil.add(point.getOriginX(), -textW * 2.2f);
                            right = LeafUtil.add(point.getOriginX(), textW * 2.2f);
                        } else if (length == 2) {
                            left = LeafUtil.add(point.getOriginX(), -textW * 1.0f);
                            right = LeafUtil.add(point.getOriginX(), textW * 1.0f);
                        } else {
                            left = LeafUtil.add(point.getOriginX(), -textW * 0.6f);
                            right = LeafUtil.add(point.getOriginX(), textW * 0.6f);
                        }
                        top = LeafUtil.add(point.getOriginY(), -2.5f * textH);
                        bottom = LeafUtil.add(point.getOriginY(), -0.5f * textH);

                        //控制位置
                        if (left < axisY.getStartX()) {
                            left = axisY.getStartX();
                            right = LeafUtil.add(right, left);
                        }
                        if (top < 0) {
                            top = topPadding;
                            bottom = LeafUtil.add(bottom, topPadding);
                        }
                        if (right > mWidth) {
                            right = LeafUtil.add(right, -rightPadding);
                            left = LeafUtil.add(left, -rightPadding);
                        }


                        RectFloat rectF = new RectFloat(LeafUtil.add(left, moveX), top, LeafUtil.add(right, moveX), bottom);
                        float labelRadius = LeafUtil.dp2px(mContext, chartData.getLabelRadius());
                        labelPaint.setColor(new Color(chartData.getLabelColor()));
                        labelPaint.setStyle(Paint.Style.FILL_STYLE);
                        canvas.drawRoundRect(rectF, labelRadius, labelRadius, labelPaint);

                        //drawText
                        labelPaint.setColor(Color.WHITE);
                        float xCoordinate = LeafUtil.add(left, LeafUtil.add(right, -left, -textW) / 2, moveX);
                        float yCoordinate = LeafUtil.add(bottom, -LeafUtil.add(bottom, -top, -textH) / 2);
                        canvas.drawText(labelPaint, point.getLabel(), xCoordinate, yCoordinate);
                    }
                    canvas.restore();
                }
            }
        }
    }

    /**
     * 带动画的绘制
     *
     * @param duration
     */
    public void showWithAnimation(int duration) {
//        isAnimateEnd = false;
//        ObjectAnimator animator = ObjectAnimator.ofFloat(this, "phase", 0.0f, 1.0f);
//        animator.setDuration(duration);
//        animator.start();
//        isShow = true;
//
//        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//            @Override
//            public void onAnimationUpdate(ValueAnimator animation) {
//                phase = (float) animation.getAnimatedValue();
//            }
//        });
//
//        animator.addListener(new Animator.AnimatorListener() {
//            @Override
//            public void onAnimationStart(Animator animation) {
//            }
//
//            @Override
//            public void onAnimationEnd(Animator animation) {
//                isAnimateEnd = true;
//            }
//
//            @Override
//            public void onAnimationCancel(Animator animation) {
//
//            }
//
//            @Override
//            public void onAnimationRepeat(Animator animation) {
//
//            }
//        });
        isShow = true;
        isAnimateEnd = true;
    }


    //showWithAnimation动画开启后会调用该方法
    public void setPhase(float phase) {
        chartView.invalidate();
    }

    private PathEffect createPathEffect(float pathLength, float phase, float offset) {
        return new PathEffect(new float[]{phase * pathLength, pathLength}, 0);
    }


}
